package com.glsc.ngateway.platform.service.itflow.flowstrategy.equipmentApply.taskPostHandler;

import com.glsc.ngateway.common.api.common.enums.RabbitExcQueConstant;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItCloudDevice;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItVirtualDevice;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEquipmentApply;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEquipmentApplyCloudDeviceDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEquipmentApplyVirtualDeviceDetail;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.equipment.EquipmentPassParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.equipment.EquipmentRejectParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.equipment.EquipmentApplyTaskFormDataDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.equipment.domainDto.FlowFormEquipmentApplyDto;
import com.glsc.ngateway.common.api.flowable.dto.task.message.EquipmentFlowMessageDto;
import com.glsc.ngateway.common.api.flowable.resp.ResponseSituationDto;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEquipmentApplyCloudDeviceRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEquipmentApplyRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEquipmentApplyVirtualDeviceRepo;
import com.glsc.ngateway.platform.service.FlowCommonService;
import com.glsc.ngateway.platform.service.it.CloudService;
import com.glsc.ngateway.platform.service.it.VirtualService;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.AbstractHandlerHelper;
import com.glsc.ngateway.platform.utils.MqUtil;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowStatus;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 设备申领节点辅助类
 * @author xuchang
 */
@Component
public class EAStepHandlerHelper extends AbstractHandlerHelper {

    @Autowired
    private CloudService cloudService;

    @Autowired
    private VirtualService virtualService;

    @Autowired
    private FlowFormEquipmentApplyVirtualDeviceRepo equipmentApplyVirtualDeviceRepo;

    @Autowired
    private FlowFormEquipmentApplyCloudDeviceRepo equipmentApplyCloudServerRepo;

    @Autowired
    private FlowFormEquipmentApplyRepo equipmentApplyRepo;

    @Autowired
    private FlowCommonService flowCommonService;

    protected void endTaskAfterHandle(EquipmentPassParamDto<FlowFormEquipmentApplyDto, EquipmentApplyTaskFormDataDto> param, String operator, @NotNull String mqCodeKey) {
        ResponseSituationDto processInfo = flowCommonService.getProcessInfo(param.getProcessId());
        if(Collections.isEmpty(processInfo.getCurrentTaskInfoDtoList())){
            EquipmentFlowMessageDto message = new EquipmentFlowMessageDto();
            FlowFormEquipmentApply apply = equipmentApplyRepo.findByProcessId(param.getProcessId());
            message.setMainFormId(apply.getId());
            message.setDefineKey(mqCodeKey);
            message.setOperator(operator);
            MqUtil.sendMessage(RabbitExcQueConstant.AMPRODUCT_EXCHANGE_DEFAULT, RabbitExcQueConstant.AMPRODUCT_QUEUE_GATEWAY_FLOW_REMIND, message);
        }
    }

    /**
     * 驳回后置处理方法
     */
    protected void afterHandle(@NotNull EquipmentRejectParamDto param, @NotNull String operator) {
        List<FlowFormEquipmentApply> formDataList = equipmentApplyRepo.findAllByProcessId(param.getProcessId());
        formDataList.forEach(f->{
            f.setUpdateAccount(operator);
        });
        equipmentApplyRepo.saveAll(formDataList);
    }

    public void applyEquipment(Long mainFormId) {
        FlowFormEquipmentApply apply = equipmentApplyRepo.findById(mainFormId)
                .orElseThrow(()-> PlatformException.error(String.format("设备申领，消息处理异常：未找到主表数据，%s", mainFormId)));
        //幂等
        if(apply.getIsClose() == 0){
            //审核通过后需要新增设备的信息
            //增加虚拟机
            applyVirtualDevice(mainFormId);
            //增加云平台
            applyCloudServer(mainFormId);
            apply.setStatus(ITFlowStatus.END.getCode());
            apply.setIsClose(1);
            equipmentApplyRepo.save(apply);
        }
    }

    private void applyVirtualDevice(Long mainFormId) {
        List<FlowFormEquipmentApplyVirtualDeviceDetail> applyVirtualList
                = equipmentApplyVirtualDeviceRepo.findByEquipmentApplyId(mainFormId);
        applyVirtualList.forEach(virtual->{
            ItVirtualDevice convert = new ItVirtualDevice();
            convert.setBusinessName(virtual.getBusinessName());
            convert.setApplicationDetail(virtual.getApplicationDetail());
            convert.setMachineArea(virtual.getMachineArea());
            convert.setVirtualName(virtual.getVirtualName());
            convert.setOperationSys(virtual.getOperationSys());
            convert.setVcentIp(virtual.getVcentIp());
            convert.setVirtualIp(virtual.getVirtualIp());
            convert.setQj(virtual.getQj());
            convert.setCpu(virtual.getCpu());
            convert.setMemory(virtual.getMemory());
            convert.setUserId(virtual.getUserId());
            convert.setBz(virtual.getBz());
            convert.setIp1(virtual.getIp1());
            convert.setIp2(virtual.getIp2());
            convert.setIp3(virtual.getIp3());
            convert.setIp4(virtual.getIp4());
            convert.setMac1(virtual.getMac1());
            convert.setMac2(virtual.getMac2());
            convert.setBf(virtual.getBf());
            convert.setNetworkSegment(virtual.getNetworkSegment());
//            convert.setMark(virtual.getMark());
            virtualService.addOrUpdateVirtual(convert);
        });
    }

    private void applyCloudServer(Long mainFormId) {
        List<FlowFormEquipmentApplyCloudDeviceDetail> applyCloudList = equipmentApplyCloudServerRepo.findByEquipmentApplyId(mainFormId);
        applyCloudList.forEach(cloud->{
            ItCloudDevice convert = new ItCloudDevice();
            convert.setCloudId(cloud.getCloudId());
            convert.setCloudStyle(cloud.getCloudStyle());
            convert.setCloudArea(cloud.getCloudArea());
            convert.setInsideIp(cloud.getInsideIp());
            convert.setEip(cloud.getEip());
            convert.setSlb(cloud.getSlb());
            convert.setOperationSys(cloud.getOperationSys());
            convert.setCpu(cloud.getCpu());
            convert.setMemory(cloud.getMemory());
            convert.setUserId(cloud.getUserId());
            convert.setManageControl(cloud.getManageControl());
            convert.setMasterName(cloud.getMasterName());
//            convert.setMark(cloud.getMark());
            convert.setApplication(cloud.getApplication());
            cloudService.addOrUpdateCloud(convert);
        });
    }

    /**
     * 更新剩余信息
     */
    protected void fillOtherData(EquipmentApplyTaskFormDataDto data) {
        data.getFormVirtualDeviceDataList().forEach(virtual->{
            FlowFormEquipmentApplyVirtualDeviceDetail virtualApply = equipmentApplyVirtualDeviceRepo.findById(virtual.getId())
                    .orElseThrow(()-> PlatformException.error("设备申领，异常：未找到虚拟机子表数据"));
            virtualApply.setVirtualName(virtual.getVirtualName());
            virtualApply.setVcentIp(virtual.getVcentIp());
            virtualApply.setVirtualIp(virtual.getVirtualIp());
            virtualApply.setQj(virtual.getQj());
            virtualApply.setNetworkSegment(virtual.getNetworkSegment());
            equipmentApplyVirtualDeviceRepo.save(virtualApply);
        });
        data.getFormCloudDeviceDataList().forEach(cloud->{
            FlowFormEquipmentApplyCloudDeviceDetail cloudApply = equipmentApplyCloudServerRepo.findById(cloud.getId())
                    .orElseThrow(()-> PlatformException.error("设备申领，异常：未找到云平台子表数据"));
            cloudApply.setCloudId(cloud.getCloudId());
            cloudApply.setCloudStyle(cloud.getCloudStyle());
            cloudApply.setCloudArea(cloud.getCloudArea());
            cloudApply.setEip(cloud.getEip());
            cloudApply.setSlb(cloud.getSlb());
            cloudApply.setManageControl(cloud.getManageControl());
            cloudApply.setMasterName(cloud.getMasterName());
            cloudApply.setInsideIp(cloud.getInsideIp());
            //TODO 少"业务网段"和"ILO"
            equipmentApplyCloudServerRepo.save(cloudApply);
        });
    }
}
